using System;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;

namespace Hotfix.Runtime
{
    public static class UIBindingSystem
    {
        public static void AutoBind(UIBase ui)
        {
            var type = ui.GetType();
            var flags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            BindComponents(ui, type, flags);
            BindEvents(ui, type, flags);
        }
        
        private static void BindComponents(UIBase ui, Type type, BindingFlags flags)
        {
            foreach (var field in type.GetFields(flags))
            {
                var bindAttr = field.GetCustomAttribute<UIComponentBindAttribute>();
                if (bindAttr != null)
                {
                    var component = ui.transform.Find(bindAttr.Path)?.GetComponent(field.FieldType);
                    if (component != null)
                    {
                        field.SetValue(ui, component);
                    }
                    else
                    {
                        Debug.LogError($"组件绑定失败：路径 {bindAttr.Path} 未找到 {field.FieldType.Name} 组件");
                    }
                }
            }
        }
        
        private static void BindEvents(UIBase ui, Type type, BindingFlags flags)
        {
            foreach (var method in type.GetMethods(flags))
            {
                BindButton(ui, method);
                BindToggle(ui, method);
                BindSlider(ui, method);
                BindInputField(ui, method);
            }
        }
        
         private static void BindButton(UIBase ui, MethodInfo method)
        {
            var attr = method.GetCustomAttribute<UIButtonBindAttribute>();
            if (attr == null) return;

            var button = ui.transform.Find(attr.Path)?.GetComponent<Button>();
            if (button == null)
            {
                Debug.LogError($"按钮绑定失败：路径 {attr.Path} 未找到Button组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), Type.EmptyTypes))
            {
                Debug.LogError($"按钮方法签名错误：{method.Name} 必须是无参void方法");
                return;
            }

            button.onClick.AddListener(() => method.Invoke(ui, null));
        }

        private static void BindToggle(UIBase ui, MethodInfo method)
        {
            var attr = method.GetCustomAttribute<UIToggleBindAttribute>();
            if (attr == null) return;

            var toggle = ui.transform.Find(attr.Path)?.GetComponent<Toggle>();
            if (toggle == null)
            {
                Debug.LogError($"Toggle绑定失败：路径 {attr.Path} 未找到Toggle组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(bool) }))
            {
                Debug.LogError($"Toggle方法签名错误：{method.Name} 必须是 void Method(bool)");
                return;
            }

            toggle.onValueChanged.AddListener(value => method.Invoke(ui, new object[] { value }));
        }

        private static void BindSlider(UIBase ui, MethodInfo method)
        {
            var attr = method.GetCustomAttribute<UISliderBindAttribute>();
            if (attr == null) return;

            var slider = ui.transform.Find(attr.Path)?.GetComponent<Slider>();
            if (slider == null)
            {
                Debug.LogError($"Slider绑定失败：路径 {attr.Path} 未找到Slider组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(float) }))
            {
                Debug.LogError($"Slider方法签名错误：{method.Name} 必须是 void Method(float)");
                return;
            }

            slider.onValueChanged.AddListener(value => method.Invoke(ui, new object[] { value }));
        }

        private static void BindInputField(UIBase ui, MethodInfo method)
        {
            var attr = method.GetCustomAttribute<UIInputFieldBindAttribute>();
            if (attr == null) return;

            var inputField = ui.transform.Find(attr.Path)?.GetComponent<InputField>();
            if (inputField == null)
            {
                Debug.LogError($"InputField绑定失败：路径 {attr.Path} 未找到InputField组件");
                return;
            }

            if (!ValidateMethodSignature(method, typeof(void), new[] { typeof(string) }))
            {
                Debug.LogError($"InputField方法签名错误：{method.Name} 必须是 void Method(string)");
                return;
            }

            inputField.onValueChanged.AddListener(value => method.Invoke(ui, new object[] { value }));
        }

        private static bool ValidateMethodSignature(MethodInfo method, Type returnType, Type[] parameterTypes)
        {
            if (method.ReturnType != returnType) return false;
            
            var parameters = method.GetParameters();
            if (parameters.Length != parameterTypes.Length) return false;

            for (int i = 0; i < parameters.Length; i++)
            {
                if (parameters[i].ParameterType != parameterTypes[i])
                    return false;
            }

            return true;
        }
        
    }
}